/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package plash.display;

import plash.events.KeyEvent;
import processing.core.PGraphics;
import processing.event.MouseEvent;

/**
 *
 * @author User
 */
public class InteractiveObject extends DisplayObject
{
    protected int __tabIndex = 0;
    protected boolean __mouseInside = false;
    protected boolean __doubleClickEnabled = false;
    protected boolean __mouseEnabled = true;
    protected boolean __tabEnabled = true;
    protected boolean __rolledOver = false;
    
    public InteractiveObject()
    {
        super();
    }

    protected void __registerMouseEvents()
    {
        if (this.__stage == null)
        {
            return;
        }
        try
        {
            __stage.unregisterMethod("mouseEvent", this);
        }
        catch (RuntimeException re)
        {
        }
        if (__mouseEnabled)
        {
            __stage.registerMethod("mouseEvent", this);
        }
    }

    protected void __registerKeyEvents()
    {
        if (this.__stage == null)
        {
            return;
        }
        try
        {
            __stage.unregisterMethod("keyEvent", this);
        }
        catch (RuntimeException re)
        {
        }
        __stage.registerMethod("keyEvent", this);
    }

    protected void _updateInteractionMechanisms()
    {
        if (__parent == null)
        {
            return;
        }
        __registerKeyEvents();
        __registerMouseEvents();
    }
    
    @Override
    public void refresh()
    {
        super.refresh();
        _updateInteractionMechanisms();
    }

    public void mouseEvent(processing.event.MouseEvent me)
    {
        int actionId = me.getAction();
        int mx;
        int my;
        int clickCount;
        
        if(!__mouseEnabled)
        {
            return;
        }
        
        mx = me.getX() + this.__x;
        my = me.getY() + this.__y;
        
        __mouseX = mx;
        __mouseY = my;
 
        __mouseInside = this.getBoundingBox().containsPoint(me.getX(), me.getY());
        
        if(!__mouseInside)
        {
            if(__rolledOver)
            {
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_OUT, __mouseX, __mouseY));
                __rolledOver = false;
            }
            return;
        }
                
        switch(actionId)
        {
            case MouseEvent.PRESSED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_DOWN, mx, my));
                break;
            case MouseEvent.CLICKED:
                clickCount = me.getClickCount();
                if(clickCount == 2)
                {
                    if(__doubleClickEnabled)
                    {
                        dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.DOUBLE_CLICK, mx, my));
                    }
                }
                else if(clickCount == 1)
                {
                    dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.CLICK, mx, my));
                }
                break;
            case MouseEvent.RELEASED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_UP, mx, my));
                break;
            case MouseEvent.MOVED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_MOVE, mx, my));
                break;
            case MouseEvent.DRAGGED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_DRAGGED, mx, my));
                break;
        }
        
        if(!__rolledOver)
        {
            dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_OVER, __mouseX, __mouseY));
            __rolledOver = true;
        }
    }

    public void keyEvent(processing.event.KeyEvent ke)
    {
        int actionId = ke.getAction();
        
        switch(actionId)
        {
            case processing.event.KeyEvent.PRESSED:
                dispatchEvent(new KeyEvent(KeyEvent.KEY_DOWN, 
                        ke.getKeyCode(), 
                        ke.getKey(),
                        ke.isShiftDown(), 
                        ke.isControlDown(),
                        ke.isAltDown()));
                break;
            case processing.event.KeyEvent.RELEASED:
                dispatchEvent(new KeyEvent(KeyEvent.KEY_UP, 
                        ke.getKeyCode(), 
                        ke.getKey(),
                        ke.isShiftDown(), 
                        ke.isControlDown(),
                        ke.isAltDown()));
                break;
        }
    }

    @Override
    public void setStage(Stage stage)
    {
        super.setStage(stage);
        _updateInteractionMechanisms();
    }

    public int getTabIndex()
    {
        return __tabIndex;
    }

    public void setTabIndex(int tabIndex)
    {
        this.__tabIndex = tabIndex;
    }

    public boolean isDoubleClickEnabled()
    {
        return __doubleClickEnabled;
    }

    public void setDoubleClickEnabled(boolean doubleClickEnabled)
    {
        this.__doubleClickEnabled = doubleClickEnabled;
    }

    public boolean isMouseEnabled()
    {
        return __mouseEnabled;
    }

    public void setMouseEnabled(boolean mouseEnabled)
    {
        this.__mouseEnabled = mouseEnabled;
        _updateInteractionMechanisms();
    }

    public boolean isTabEnabled()
    {
        return __tabEnabled;
    }

    public void setTabEnabled(boolean tabEnabled)
    {
        this.__tabEnabled = tabEnabled;
        _updateInteractionMechanisms();
    }
    
    @Override
    public PGraphics getMaskPainter()
    {
        return this.getMask().getPainter();
    }
}
